# Copyright (C) 2006  Apptility LLC  http://www.apptility.com
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

class CheckinstallController < ApplicationController
  layout 'no_app_theme'
  
  def page1 
    @ruby_version = RUBY_VERSION
    @ruby_platform = RUBY_PLATFORM
    @ruby_gem_version = Gem::RubyGemsVersion
    @rails_env = RAILS_ENV
    @rails_version = Rails::VERSION::STRING  #"Yes" #Rails has to be present, otherwise you cant even see this page. #system("rails -v")
    @app_root = File.expand_path(RAILS_ROOT)
    @config = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml" )) 
    @db_test_string = @config['development']['adapter' ]  #Mysql::COM_STATISTICS #"Found MySQL tables" #test_db_connection

   begin
     require 'net/http'
     # To get anonymous one-time performance metric. (Same as Google Analytics)
     h = Net::HTTP.new('http://www.openapp.org/ajuby/user_log.php', 80)
   rescue
   end  
  end
  
  def page2
#    @db_type = params['dbtype']
#    @config = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml" )) 
#    @config['development']['adapter' ]= @db_type  
#    if @db_type =='mysql'
#      @config['development']['socket' ]= '/tmp/mysql.sock'
#    else
#      @config['development'].delete_if{|key, value| key >= "socket" }
#    end  
#    
#    File.open( "#{RAILS_ROOT}/config/database.yml", 'w' )  do |f| 
#      f << @config.to_yaml 
#    end
  end
  
  def page3
    @hostname = params['hostname']
    if(@hostname!=nil) 
      @dbname = params['dbname']
      @dbusername = params['dbusername']
      @dbpassword = params['dbpassword']
      #AjubyLogger.logInfo "#{@hostname.length}, #{@dbname.length}, #{@dbusername.length}, #{@dbpassword.length}"
      if(@hostname.length<=0 or @dbname.length<=0 or @dbusername.length<=0)
        AjubyLogger.logInfo "Not all the required fields are entered. Please enter all the required fields are proceed."
        flash[:message] = "Not all the required fields are entered. Please enter all the required fields are proceed."
        redirect_to :action =>'page2',   :dbtype => params['dbtype']
      else
        @createdb = params['createdb']
        #@conn = is_db_exists(@dbname, @dbusername, @dbpassword)
        @msg_str = create_db(params['dbtype'], @hostname, @dbname,@dbusername, @dbpassword)
        @iserror = false
        if(@msg_str[0,6]=="Error:")
          flash[:message] = @msg_str
          @iserror = true
        else
          flash[:simplemsg] = @msg_str
          flash[:message] == nil
          update_rails_db_config(@dbname, @dbusername, @dbpassword)
          load_schema_db
        end
      end
    end 
  end

  def page4
    @odotadminusername = params['odotadminusername']
    @odotadminpassword = params['odotadminpassword']
    if(@odotadminusername.length<=0 or @odotadminpassword.length<=0)
      flash[:simplemsg] = "Not all the required fields are entered. Please enter all the required fields are proceed."
      @coming_from = "page4"
      redirect_to :action =>'page3'   
    end
    create_admin_user(@odotadminusername, @odotadminpassword)
    update_app_email_config
  end
 
  def update_app_email_config
    @emailconfigtype = params['emailconfigtype']
    @emailconfigstring = ""
    if (@emailconfigtype=='smtp')
      @smtpaddress = params['smtpaddress']
      @smtphost=params['smtphost']
      @smtpusername=params['smtpusername']
      @smtppassword=params['smtppassword']
      @emailconfigstring = "ActionMailer::Base.server_settings = {:address => '#{@smtpaddress}',:port => 25,:domain => '#{@smtphost}', :user_name =>'#{@smtpusername}', :password =>'#{@smtppassword}', :authentication => :login} "
      ActionMailer::Base.server_settings = {:address => '#{@smtpaddress}',:port => 25,:domain => '#{@smtphost}', :user_name =>'#{@smtpusername}', :password =>'#{@smtppassword}', :authentication => :login}
    else 
      @emailconfigstring = "ActionMailer::Base.delivery_method = :sendmail"
      ActionMailer::Base.delivery_method = :sendmail
    end

    f = File.open( "#{RAILS_ROOT}/config/environments/development.rb", 'r+' )
    begin
        while (line = f.readline)
          # do nothing,
        end
    rescue EOFError
        # update the email config info at the end of the file.
        f.print "\n#{@emailconfigstring}"
        f.close
    end   

  end
  
  def create_admin_user(odotadminusername, odotadminpassword)
    begin
      @user = User.find(1)
      @user.login = odotadminusername
      @user.salt = AuthenticatedUser.hashed("salt-#{Time.now}")
      @user.salted_password = AuthenticatedUser.salted_password(@user.salt, AuthenticatedUser.hashed(odotadminpassword))
      @iserror = false
      if @user.save
        flash[:simplemsg] = 'Application configuration complete.'
      end
      rescue Exception => e
        @iserror = true
        flash.now[:message] = 'Error creating admin account: ' << e.message
      end
      
  end
  
  def is_db_exists(dbname,username, password)
   ActiveRecord::Base.establish_connection(
            :adapter  => "mysql",
            :host     => "localhost",
            :username => "#{username}",
            :password => "#{password}",
            :database => "#{dbname}"
          )    
     return  ActiveRecord::Base.connection    
  end

  def establish_connection_to_core(adapter, host, dbname,username, password)
   ActiveRecord::Base.establish_connection(
            :adapter  => "#{adapter}",
            :host     => "#{host}",
            :username => "#{username}",
            :password => "#{password}",
            :database => "#{dbname}"
          )    
     return  ActiveRecord::Base.connection    
  end

  
  def load_schema_db
    require 'db/migrate/ajuby_db_migration_rel_0.4'
    AjubyDBMigration.up
    flash[:simplemsg] << "Database schema and data configured successfully."
  end
  
  def update_rails_db_config(dbname,username, password)
    @config = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml" )) 
    @config['development']['database' ]= dbname  
    @config['development']['username' ]= username
    @config['development']['password' ]= password
    
    File.open( "#{RAILS_ROOT}/config/database.yml", 'w' )  do |f| 
      f << @config.to_yaml 
    end
    
    ActiveRecord::Base.configurations = @config 
    ActiveRecord::Base.establish_connection 
  end
 
   def create_db(dbtype, hostname, dbname, dbusername, dbpassword)
    @err_message = "Database [#{dbname}] successfully created.."
    begin
     #@db_connection = establish_connection_to_core(dbtype, hostname, dbname, dbusername, dbpassword)
     ActiveRecord::Base.connection.execute("CREATE DATABASE #{dbname};")
     # ActiveRecord::Base.connection.create_database(dbname) 
     #@db_connection.execute("CREATE DATABASE #{dbname};")
    rescue => err
       @err_message = "Error: Could not database =>" << err.message
       AjubyLogger.logInfo "create_db [database name specified : #{dbname}].....ERRRRRRRRRRRRRRRGH=>" << @err_message 
    end
    return @err_message     
  end
 
 
 ################################################################################################# 
 #################### OLD CODE , Keeping it for future ref #######################################
 #################################################################################################
  def installverify
    @ruby_present = system("ruby -v")
    #@rails_present =  system("rails -v")
    @db_test_string = test_db_connection
    # ActiveRecord::ConnectionAdapters::MysqlAdapter.create_database("rajesh")
  end
  
  def createorupdatedb
    AjubyLogger.logInfo "createorupdatedb .....CONNNNNNNN=> #{ActiveRecord::Base.remove_connection()}"
    #ActiveRecord::Base.connection = nil
    @clientop = params['clientop']
    @message = ""
    AjubyLogger.logInfo "@clientop .....#{@clientop}"
    if(@clientop=="cdbschemadata")
      @message = create_db(@dbname)
      if(@message=="Database [#{@dbname}] successfully created..")
        #update_database_configuration(@dbname, @dbusername, @dbpassword)
        #load_schema_data
      end
    end 
    AjubyLogger.logInfo "###########>>>>>>>>>>>>>>>>>>>>> #{@message} "
  end

  
  def checkorcreatedb
    @db_test_string = ""
    @db_test_err_string= ""
    @db_test_msg_string=""
    @server_op =""
    
    @dbusername = params['dbusername']
    @dbpassword = params['dbpassword']
    @dbname = params['dbname']
    @op = params['op']
    @err_message ="NOMSG"
    begin
      ActiveRecord::Base.establish_connection(
          :adapter  => "mysql",
          :host     => "localhost",
          :username => "#{@dbusername}",
          :password => "#{@dbpassword}",
          :database => "#{@dbname}"
        )    
      rescue => err
         #@err_message = "Database not found=>" << err.message
         raise
      end 
     #@message = "Database already exists, Are you sure you want to override this database with the OpenAppDotOrg Toolkit schema and data?."

    begin
    	tables = ActiveRecord::Base.connection.select_all('SHOW TABLES')
    rescue Exception=> err
        if err.message =="Unknown database '#{@dbname}'"
          @db_test_msg_string= "Installer will <br>&nbsp;&nbsp;-create new database...<br>&nbsp;&nbsp;-create toolkit schema...<br>&nbsp;&nbsp;-load toolkit reference data..."
          @server_op = "createdb"
          #ActiveRecord::Base.connection.clear_active_connections
        else
    	@db_test_err_string = @db_test_err_string << "[Database connection failed]"
    	@db_test_err_string = @db_test_err_string << err.message
    	@db_test_err_string = @db_test_err_string << " Please try again, with right database parameters"
       #raise
       end
    end
    if (@db_test_msg_string=="")
      @db_test_msg_string = @db_test_string << "Database already exists, Are you sure you want to override this database with the OpenAppDotOrg Toolkit schema and data?."
    end
  end
  
   
  def test_db_connection
    @db_test_string = ""
    #ActiveRecord::Base.establish_connection
    begin
    ActiveRecord::Base.establish_connection(
        :adapter  => "mysql",
        :host     => "localhost",
        #:username => "myuser",
        #:password => "mypass",
        :database => "mysql"
      )    
    rescue => err
       @db_test_string = "Database connection Failed"
       raise
    end
    @db_test_string = "Testing database connection"
    begin
    	tables = ActiveRecord::Base.connection.select_all('SHOW TABLES')
    rescue => err
    	@db_test_string = @db_test_string << "===== database connection failed ====="
    	@db_test_string = @db_test_string << "Missing database bindings for #{err.blamed_files}" if err.message =~ /^uninitialized constant Mysql$/
       raise
    end
    @db_test_string = @db_test_string << "...Database tested OK, found core mysql #{tables.size} tables"

  end
  
  def connect_to_db_and_execute(sql,username, password, dbname, docreatenew)
    @db_test_string = ""
    if(docreatenew=="true")
      dbname_connect = "mysql"
    else
      dbname_connect = "#{dbname}"
    end
 
    begin
    ActiveRecord::Base.establish_connection(
        :adapter  => "mysql",
        :host     => "localhost",
        :username => "#{username}",
        :password => "#{password}",
        :database => "#{dbname_connect}"
      )    
    rescue => err
       @db_test_string = "connect_to_db_and_execute:Database connection Failed"
       raise
    end
    @db_test_string = "connect_to_db_and_execute:Testing database connection"
    begin
        AjubyLogger.logInfo "@@@@@@@@@@@@SQL:    #{sql}"
    	ActiveRecord::Base.connection.execute('#{sql}')
    rescue => err
    	@db_test_string = @db_test_string << "===== database connection failed ====="
    	@db_test_string = @db_test_string << "Missing database bindings for #{err.blamed_files}" if err.message =~ /^uninitialized constant Mysql$/
       raise
    end
    @db_test_string = @db_test_string << "...Database tested OK"
  
  end
  
end
